﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameJolt;
using System.Timers;
using System.IO;
using BealsSoftware.Core;
using GameJoltServices;
using GameJoltServices.News;
using GameJoltServices.Saves;

namespace TestBed
{
	class Program
	{
		private static void WaitForAsyncOperation(IAsyncResult result, string message)
		{
			var lineIndex = Console.CursorTop;
			var dotCount = 0;
			var timer = new Timer(250);
			timer.Elapsed += (sender, args) =>
			{
				++dotCount;
				if(dotCount > 3)
					dotCount = 0;
			};

			timer.Start();
			while(!result.IsCompleted)
			{
				Console.CursorTop = lineIndex;
				Console.CursorLeft = 0;
				Console.Write(message + new string('.', dotCount) + new string(' ', 3 - dotCount));
			}

			Console.CursorTop = lineIndex;
			Console.CursorLeft = 0;
			Console.WriteLine("Finished " + message);
		}

		private static void WriteUser(GameJoltServices.User user)
		{
			Console.WriteLine(string.Format("User ID: {0}", user.UserID));
			Console.WriteLine(string.Format("Username: {0}", user.Username));
			Console.WriteLine(string.Format("Last Logged In: {0}", user.LastLoggedIn));
			Console.WriteLine(string.Format("Avatar URL: {0}", user.AvatarUrl));
			Console.WriteLine(string.Format("Developer Name: {0}", user.DeveloperName));
			Console.WriteLine(string.Format("Develoer Website: {0}", user.DeveloperWebsite));
			Console.WriteLine(string.Format("Developer Description: {0}", user.DeveloperDescription));
		}

		private static void WriteTrophy(Trophy trophy)
		{
			Console.WriteLine(string.Format("({0}) {1} - \"{2}\" - {3}", trophy.ID, trophy.Title, trophy.Description, bool.Parse(trophy.Achieved) ? "Achieved" : "Locked"));
		}

		static void Main(string[] args)
		{
			string gameID = "GAMEID";
			string privateKey = "PRIVATEKEY";

			RuntimeLogWriter.Initialize(@"C:\Users\Public\GameJoltLog.txt");
			Logging.EntryLogged = (type, text) =>
			{
				if(type == "Information")
					RuntimeLog.LogInformation(text, "GameJolt");
				else if(type == "Warning")
					RuntimeLog.LogWarning(text, "GameJolt");
				else if(type == "Error")
					RuntimeLog.LogError(text, "GameJolt");
			};

			ServicesManager servicesManager = new ServicesManager(gameID, privateKey);
			GameSaveService gameSaveService = new GameSaveService(ServicesManager.GetDefaultCacheFolder("GJS Test Bed"), servicesManager);

			Console.Write("Username: ");
			var username = Console.ReadLine();
			Console.Write("Token: ");
			var userToken = Console.ReadLine();

			var user = servicesManager.LogInUser(username, userToken);
			if(user == null)
				Console.WriteLine("Failed to authenticate " + username);
			else
			{
				WriteUser(user);

				var newSave = new GameSave()
				{
					Location = "YMMGSave1",
					Name = "Donny 2",
					DateSaved = DateTime.Now,
					Username = user.Username,
					UserToken = user.UserToken,
				};

				using(var stream = new MemoryStream())
				{
					using(var writer = new BinaryWriter(stream))
					{
						writer.Write("Tungala City Square");
						writer.Write("Donny");
						writer.Write(new TimeSpan(6, 11, 15).Ticks);

						newSave.DescriptionData = Convert.ToBase64String(stream.ToArray());
					}
				}

				using(var stream = new MemoryStream())
				{
					using(var writer = new BinaryWriter(stream))
					{
						writer.Write("tungala_02");
						writer.Write("Donny");
						writer.Write("Warrior");
						writer.Write("97");
						// other data here

						newSave.SaveData = Convert.ToBase64String(stream.ToArray());
					}
				}
				var uploadResult = gameSaveService.UploadSave(newSave);

				NewsService newsService = new NewsService(servicesManager);
				var newsItems = newsService.GetNews();
				if(newsItems.Length == 0)
					Console.WriteLine("No news items.");
				else
				{
					Console.WriteLine("News: ");
					foreach(var newsItem in newsItems)
						Console.WriteLine(string.Format("{0} - {1}\n{2}\n", newsItem.DateTimePosted.ToShortDateString(), newsItem.Title, newsItem.Content));
				}

				var saves = gameSaveService.GetSaves(user);
				if(saves.Length == 0)
					Console.WriteLine("No game saves.");
				else
				{
					foreach(var save in saves)
					{
						if(!save.IsCached)
							gameSaveService.DownloadSave(save);

						Console.WriteLine("{0} - {1} - {2}", save.Location, save.Name, save.DateSaved);
						using(var stream = save.GetDataStream())
						{
							using(var reader = new BinaryReader(stream))
							{
								Console.WriteLine(reader.ReadString());
								Console.WriteLine(reader.ReadString());
								Console.WriteLine(reader.ReadString());
								Console.WriteLine(reader.ReadString());
							}
						}
					}
				}
			}
			Console.ReadKey(true);
		}
	}
}
